package cn.com.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import com.wf.captcha.utils.CaptchaUtil;

import cn.com.common.aop.annotation.LogAnnotation;
import cn.com.common.constants.Constants;
import cn.com.system.entity.SysLoginIdentityEntity;
import cn.com.system.entity.SysRole;
import cn.com.system.entity.SysUser;
import cn.com.system.entity.SysUserIdentityEntity;
import cn.com.system.entity.SysUserRole;
import cn.com.system.mapper.SysLogMapper;
import cn.com.common.exception.code.BaseResponseCode;
import cn.com.common.result.DataResult;
import cn.com.gt3.entity.DmQxSwrysfEntity;
import cn.com.gt3.service.DmGySwjgService;
import cn.com.gt3.service.DmQxSwrysfService;
import cn.com.system.service.DeptService;
import cn.com.system.service.PermissionService;
import cn.com.system.service.RedisService;
import cn.com.system.service.RoleService;
import cn.com.system.service.SysLoginIdentityService;
import cn.com.system.service.SysUserIdentityService;
import cn.com.system.service.UserRoleService;
import cn.com.system.service.UserService;
import cn.com.system.service.impl.HttpSessionService;
import cn.com.system.vo.req.UserRoleOperationReqVO;
import cn.com.system.vo.res.UserOwnRoleRespVO;
import cn.com.util.AesEncryptUtils;
import cn.com.util.TsBqUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 用户管理
 *
 * @author wenbin
 * @version V1.0
 * @date 2020年3月18日
 */
@RestController
@Api(tags = "组织模块-用户管理")
@RequestMapping("/sys")
public class UserController {

	@Resource
	private UserService userService;
	@Resource
	private DeptService deptService;
	@Resource
	private UserRoleService userRoleService;
	@Resource
	private HttpSessionService httpSessionService;
	@Resource
	private DmGySwjgService dmGySwjgService;
	@Resource
	private DmQxSwrysfService dmQxSwrysfService;
	@Resource
	private RoleService roleService;
	@Resource
	private SysLoginIdentityService sysLoginIdentityService;
	@Resource
	private PermissionService permissionService;
	@Resource
	private SysLogMapper sysLogMapper;
	@Resource
	private SysUserIdentityService sysUserIdentityService;
	@Resource
	private RedisService redisService;
	@Value("${spring.redisToken.key.prefix.userToken}")
	private String userTokenPrefix;

	
	
	@PostMapping(value = "/user/login")
	@ApiOperation(value = "用户登录接口")
	public DataResult login(@RequestBody @Valid SysUser vo, HttpServletRequest request) {
		
		// 解密处理
		try {
			vo.setCaptcha(AesEncryptUtils.decrypt(vo.getCaptcha(), "abcdef0123456789"));
			vo.setUsername(AesEncryptUtils.decrypt(vo.getUsername(), "abcdef0123456789"));
			vo.setPassword(AesEncryptUtils.decrypt(vo.getPassword(), "abcdef0123456789"));

		} catch (Exception e) {

			e.printStackTrace();
			return DataResult.fail("解密失败，请稍后重试！");
		}

		// 判断验证码
		if (!CaptchaUtil.ver(vo.getCaptcha(), request)) {
			// 清除session中的验证码
			CaptchaUtil.clear(request);
			return DataResult.fail("验证码错误！");
		}
		
		CaptchaUtil.clear(request);
		
		return DataResult.success(userService.login(vo, request));
	}

	@PostMapping("/user/register")
	@ApiOperation(value = "用户注册接口")
	public DataResult register(@RequestBody @Valid SysUser vo) {
		userService.register(vo);
		return DataResult.success();
	}

	@GetMapping("/user/unLogin")
	@ApiOperation(value = "引导客户端去登录")
	public DataResult unLogin() {
		return DataResult.getResult(BaseResponseCode.TOKEN_ERROR);
	}

	@PutMapping("/user")
	@ApiOperation(value = "更新用户信息接口")
	@LogAnnotation(title = "用户管理", action = "更新用户信息")
	@RequiresPermissions("sys:user:update")
	public DataResult updateUserInfo(@RequestBody SysUser vo) {
		if (StringUtils.isEmpty(vo.getId())) {
			return DataResult.fail("id不能为空");
		}

		userService.updateUserInfo(vo);
		return DataResult.success();
	}

	@PutMapping("/user/info")
	@ApiOperation(value = "更新用户信息接口")
	@LogAnnotation(title = "用户管理", action = "更新用户信息")
	public DataResult updateUserInfoById(@RequestBody SysUser vo) {
		userService.updateUserInfoMy(vo);
		return DataResult.success();
	}

	@PutMapping("/user/switchidentity")
	@ApiOperation(value = "切换用户身份接口")
	@LogAnnotation(title = "用户管理", action = "切换用户身份接口")
	public DataResult switchUserInfoById(@RequestBody SysUser vo) {
		String currentUserId = httpSessionService.getCurrentUserId();
		// 保存到新表里面
		String swrysfDm1 = vo.getIdentityId1();
		String sfswjgDm1 = vo.getIdentityTaxorgCode1();
		String rysfmc1 = vo.getIdentityName1();
		if(TsBqUtils.isNotNull(swrysfDm1)&&TsBqUtils.isNotNull(sfswjgDm1)&&TsBqUtils.isNotNull(rysfmc1)){
			SysLoginIdentityEntity sysLoginIdentityEntity = new SysLoginIdentityEntity();
			
			sysLoginIdentityEntity.setSwryDm(currentUserId);        
			sysLoginIdentityEntity.setSwrysfDm(swrysfDm1);     
			sysLoginIdentityEntity.setSfswjgDm(sfswjgDm1);     
			sysLoginIdentityEntity.setRysfmc(rysfmc1);  
			  
			sysLoginIdentityEntity.setCreateId(currentUserId);  
			     
			sysLoginIdentityEntity.setCreateTime(new Date());
			
			sysLoginIdentityService.saveOrUpdate(sysLoginIdentityEntity);
			
			
		}
		
		
		
		String swrysfDm = vo.getIdentityId();
		String sfswjgDm = vo.getIdentityTaxorgCode();
		String rysfmc = vo.getIdentityName();

		String token = httpSessionService.getTokenFromHeader();
		
		List<String> roles = roleService.getRoleNames(swrysfDm);
		List<String> rolesId = roleService.getRoleIds(swrysfDm);
		Set<String> permissions = permissionService.getPermissionsByUserId(swrysfDm);
		
		JSONObject currentSession = httpSessionService.getCurrentSession();
		
		currentSession.put(Constants.ROLES_KEY, roles);
		currentSession.put(Constants.ROLES_ID, rolesId);
		currentSession.put(Constants.PERMISSIONS_KEY, permissions);
		
		currentSession.put(Constants.DEPT_ID, sfswjgDm);
		currentSession.put(Constants.DEPT_NO, sfswjgDm);
		currentSession.put(Constants.IDENTITY_NO, swrysfDm);
		currentSession.put(Constants.IDENTITY_NAME, rysfmc);

		// 更新redis
		redisService.set(userTokenPrefix + token, currentSession.toJSONString());
		
		List<String> list = new ArrayList<>();
		list.add(swrysfDm);
		list.add(token);
		if(TsBqUtils.isNotNull(rolesId)){
			list.add(rolesId.toString());
		}else{
			list.add("");
		}
		
		
		return DataResult.success(list);

	}

	@GetMapping("/user/{id}")
	@ApiOperation(value = "查询用户详情接口")
	@LogAnnotation(title = "用户管理", action = "查询用户详情")
	@RequiresPermissions("sys:user:detail")
	public DataResult detailInfo(@PathVariable("id") String id) {
		SysUser sysUser = userService.getById(id);

		return DataResult.success(sysUser);
	}

	@GetMapping("/user")
	@ApiOperation(value = "查询用户详情接口")
	@LogAnnotation(title = "用户管理", action = "查询用户详情")
	public DataResult youSelfInfo() {
		String userId = httpSessionService.getCurrentUserId();
		SysUser sysUser = userService.getById(userId);

		return DataResult.success(sysUser);
	}

	@GetMapping("/user/identity")
	@ApiOperation(value = "查询用户身份接口")
	@LogAnnotation(title = "用户管理", action = "查询用户身份详情")
	public DataResult identity() {
		String userId = httpSessionService.getCurrentUserId();

		List<DmQxSwrysfEntity> list = dmQxSwrysfService.getByUserId(userId);
		SysLoginIdentityEntity sysLoginIdentityEntity = sysLoginIdentityService.getById(userId);
		
		if(TsBqUtils.isNotNull(sysLoginIdentityEntity)){
			String swrysfDm1 = sysLoginIdentityEntity.getSwrysfDm();
			List<DmQxSwrysfEntity> listHandle = new ArrayList<>();
			for (DmQxSwrysfEntity dmQxSwrysfEntity : list) {
				dmQxSwrysfEntity.setZsfbz("N");
				String swrysfDm2 = dmQxSwrysfEntity.getSwrysfDm();
				if(swrysfDm1.equals(swrysfDm2)){
					dmQxSwrysfEntity.setZsfbz("Y");
				}
				listHandle.add(dmQxSwrysfEntity);
			}
			
			return DataResult.success(listHandle);
			
		}else{
			return DataResult.success(list);
			
		}
		
	}

	@PostMapping("/users")
	@ApiOperation(value = "分页获取用户列表接口")
	@RequiresPermissions("sys:user:list")
	@LogAnnotation(title = "用户管理", action = "分页获取用户列表")
	public DataResult pageInfo(@RequestBody SysUser vo) {
		
		IPage<SysUserIdentityEntity> iPage = userService.pageInfo(vo);
		
		List<SysUserIdentityEntity> records = iPage.getRecords();
		for (SysUserIdentityEntity userIdentity : records) {
			String deptId = userIdentity.getDeptId();
			
			userIdentity.setDeptName(deptService.getById(deptId).getName());

			String userId = userIdentity.getUserId();
			
			SysUser sysUser = userService.getUser(userId);
			
			userIdentity.setPhone(sysUser.getPhone());

		}
		
		return DataResult.success(iPage);
	}

	@PostMapping("/user")
	@ApiOperation(value = "新增用户接口")
	@RequiresPermissions("sys:user:add")
	@LogAnnotation(title = "用户管理", action = "新增用户")
	public DataResult addUser(@RequestBody @Valid SysUser vo) {
		userService.addUser(vo);
		return DataResult.success();
	}

	@GetMapping("/user/logout")
	@ApiOperation(value = "退出接口")
	@LogAnnotation(title = "用户管理", action = "退出")
	public DataResult logout() {
		httpSessionService.abortUserByToken();
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		return DataResult.success();
	}

	@PutMapping("/user/pwd")
	@ApiOperation(value = "修改密码接口")
	@LogAnnotation(title = "用户管理", action = "更新密码")
	public DataResult updatePwd(@RequestBody SysUser vo) {
		if (StringUtils.isEmpty(vo.getOldPwd()) || StringUtils.isEmpty(vo.getNewPwd())) {
			return DataResult.fail("旧密码与新密码不能为空");
		}
		String userId = httpSessionService.getCurrentUserId();
		vo.setId(userId);
		userService.updatePwd(vo);
		return DataResult.success();
	}

	@DeleteMapping("/user")
	@ApiOperation(value = "删除用户接口")
	@LogAnnotation(title = "用户管理", action = "删除用户")
	@RequiresPermissions("sys:user:deleted")
	public DataResult deletedUser(@RequestBody @ApiParam(value = "用户id集合") List<String> userIds) {
		// 删除用户， 删除redis的绑定的角色跟权限
		httpSessionService.abortUserByUserIds(userIds);
		LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.in(SysUser::getId, userIds);
		userService.remove(queryWrapper);
			
		
		LambdaQueryWrapper<SysUserIdentityEntity> queryWrapper1 = Wrappers.lambdaQuery();
		queryWrapper1.in(SysUserIdentityEntity::getUserId, userIds);
		sysUserIdentityService.remove(queryWrapper1);
		return DataResult.success();
		
	}

	@GetMapping("/user/roles/{userId}")
	@ApiOperation(value = "赋予角色-获取所有角色接口")
	@LogAnnotation(title = "用户管理", action = "赋予角色-获取所有角色接口")
	@RequiresPermissions("sys:user:role:detail")
	public DataResult getUserOwnRole(@PathVariable("userId") String userId) {
		// String currentDeptId = httpSessionService.getCurrentDeptId();
		SysUserIdentityEntity sysUserIdentityEntity = sysUserIdentityService.getById(userId);
		
		String taxOrgLevel = TsBqUtils.getTaxOrgLevel(sysUserIdentityEntity.getDeptId());
		
		DataResult result = DataResult.success();

		UserOwnRoleRespVO userOwnRole = userService.getUserOwnRole(userId);

		List<SysRole> allRole = userOwnRole.getAllRole();

		List<SysRole> allRole1 = new ArrayList<>();

		for (SysRole sysRole : allRole) {
			
			String dataScope = String.valueOf(sysRole.getDataScope());
			
			if(taxOrgLevel.equals(Constants.TAX_PROVINCES)){
				// 省级
				allRole1.add(sysRole);
			}else if(taxOrgLevel.equals(Constants.TAX_CITIES)){
				// 市局
				if (dataScope.equals(Constants.TAX_CITIES_POWER)) {
					allRole1.add(sysRole);
					
				}
				
			}else if(taxOrgLevel.equals(Constants.TAX_COUNTES)){
				// 县区局
				if (dataScope.equals(Constants.TAX_COUNTES_POWER)) {
					allRole1.add(sysRole);
				}
			}
			
		}

		userOwnRole.setAllRole(allRole1);
		result.setData(userOwnRole);
		return result;

	}

	@PutMapping("/user/roles/{userId}")
	@ApiOperation(value = "赋予角色-用户赋予角色接口")
	@LogAnnotation(title = "用户管理", action = "赋予角色-用户赋予角色接口")
	@RequiresPermissions("sys:user:update:role")
	public DataResult setUserOwnRole(@PathVariable("userId") String userId, @RequestBody List<String> roleIds) {

		LambdaQueryWrapper<SysUserRole> queryWrapper = Wrappers.lambdaQuery();
		queryWrapper.eq(SysUserRole::getUserId, userId);
		userRoleService.remove(queryWrapper);
		if (null != roleIds && !roleIds.isEmpty()) {
			UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO();
			reqVO.setUserId(userId);
			reqVO.setRoleIds(roleIds);
			userRoleService.addUserRoleInfo(reqVO);
		}
		httpSessionService.refreshUerId(userId);
		return DataResult.success();
	}
}
